package com.yonyou.pmclouds.project.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.iuap.tenant.sdk.UserCenter;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.IllegalRequestArgException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.CodeNameUtils;
import com.yonyou.pmclouds.enterprise.entity.EnterpriseInfo;
import com.yonyou.pmclouds.outter.enterprise.EnterpriseInfoQuery;
import com.yonyou.pmclouds.outter.user.UserInfoQuery;
import com.yonyou.pmclouds.plan.entity.PlanBillStatus;
import com.yonyou.pmclouds.plan.entity.PlanTempletVO;
import com.yonyou.pmclouds.plan.entity.ProjectPlanVO;
import com.yonyou.pmclouds.plan.rmiitf.PlanTempletService;
import com.yonyou.pmclouds.plan.rmiitf.ProjectPlanMaintain;
import com.yonyou.pmclouds.project.entity.ProjectConst;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.entity.ProjectViewVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectOutterMaintain;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseVO;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseViewVO;
import com.yonyou.pmclouds.team.entity.TeamMemberVO;
import com.yonyou.pmclouds.team.entity.TeamMemberViewVO;
import com.yonyou.pmclouds.user.entity.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description:
 * @Author: zhangwce
 * @Date: 2018/5/7 15:04
 */
@Slf4j
@Controller
@RequestMapping(value = "/outter/project")
public class ProjectOutterController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectOutterMaintain projectOutterMaintain;
    @Autowired
    private EnterpriseInfoQuery enterpriseInfoQuery;
    @Autowired
    private UserInfoQuery userInfoQuery;
    private ObjectMapper objectMapper = new ObjectMapper();

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectSimpleQuery query;


    @ResponseBody
    @RequestMapping(value = "/insertFromOutter")
    public ProjectVO insert(@RequestBody ProjectVO project,
                            HttpServletRequest request) throws BusinessException {
        String tenantId = request.getHeader("accountId");
        String enterId = request.getHeader("enterId");
        log.debug("项目档案推送保存：租户ID："+tenantId+"，企业ID："+enterId);
        if(StringUtils.isEmpty(tenantId))
            throw new BusinessException("未找到对应租户信息");
        RuntimeEnvironment.setTenantId(tenantId);
        // 校验名称和编码的合法性
        if (checkOutCodeChar(project.getScode()) >= 0 || CodeNameUtils.checkNameStr(project.getSname(), null) >= 0) {
            throw new IllegalRequestArgException();
        }
        ProjectViewVO viewVO = genProjectViewVO(project, RuntimeEnvironment.getTenantId(),enterId);

        projectOutterMaintain.insertFromOutter(viewVO);

        return project;
    }

    private  int checkOutCodeChar(String code) {
        for (int i = 0; i < code.length(); i++) {
            if (!checkCodeChar(code.charAt(i))) {
                return i;
            }
        }
        return -1;
    }

    private boolean checkCodeChar(char c){
        if (CodeNameUtils.isLatin(c)) {
            return true;
        }
        if (c >= '0' && c <= '9') {
            return true;
        }
        return c == '-' || c == '_' || c =='.';
    }

    /**
     * 根据入参生成项目档案
     * @param project
     * @param tenantId
     * @return
     * @throws BusinessException
     */
    private ProjectViewVO genProjectViewVO(@RequestBody ProjectVO project, String tenantId, String enterId) throws BusinessException {
        ProjectViewVO viewVO = new ProjectViewVO();

        for (String field :
                ProjectViewVO.transFields) {
            BeanHelper.setProperty(viewVO,field,BeanHelper.getProperty(project,field));
        }
        viewVO.setPkTenant(tenantId);

        // 根据负责人手机号码判断该负责人是否在该租户下，并设置相关信息
        if(StringUtils.isNotEmpty(project.getManagerMobile())){
            String userId = userExistInTenant(project.getManagerMobile(), tenantId);
            if(StringUtils.isNotEmpty(userId)){
                setTeamInfo(tenantId, viewVO, userId,enterId);
            }
        }

        String creatorId = "";
        if(StringUtils.isNotEmpty(project.getCreatorMobile())){
            creatorId = userExistInTenant(project.getCreatorMobile(), tenantId);

            if(StringUtils.isNotEmpty(creatorId)){
                RuntimeEnvironment.setLoginUserId(creatorId);
            }
        }

        if(StringUtils.isEmpty(creatorId)) {
            creatorId = ProjectConst.NCUSERDEFAULTID;
            RuntimeEnvironment.setLoginUserId(creatorId);
        }
        return viewVO;
    }

    private void setTeamInfo(String tenantId, ProjectViewVO viewVO, String userId,String enterId) throws BusinessException {

        String enterprise = getOwnEnter(userId, enterId);

        viewVO.setManager(userId);

        TeamMemberViewVO memberViewVO = new TeamMemberViewVO();
        memberViewVO.setPkUser(userId);
        memberViewVO.setPkTenant(tenantId);
        memberViewVO.setUserRole(TeamMemberVO.UserRoleConst.ROLE_MANAGER);
        memberViewVO.setPkEnterprise(enterprise);

        TeamEnterpriseViewVO entViewVO = new TeamEnterpriseViewVO();
        entViewVO.setPkEnterprise(enterprise);
        entViewVO.setEntRole(TeamEnterpriseVO.EnterpriseRoleConst.ROLE_OWNER);
        entViewVO.setPkTenant(tenantId);

        entViewVO.setTeamMemberViewVOs(new TeamMemberViewVO[]{memberViewVO});
        viewVO.setTeamEnterpriseViewVOs(new TeamEnterpriseViewVO[]{entViewVO});
    }

    /**
     * 获取用户所属企业
     * @param userId
     * @param enterId
     * @return
     * @throws BusinessException
     */
    private String getOwnEnter(String userId, String enterId) throws BusinessException {
        EnterpriseInfo[] ents = enterpriseInfoQuery.getEnterprisesOfUser(userId);
        if (ArrayUtils.isEmpty(ents)) {
            throw new BusinessException("项目经理不从属于任何企业，无法创建项目！");
        }

        String enterprise = "";
        if(StringUtils.isNotEmpty(enterId)){
            for(EnterpriseInfo entInfo : ents){
                if(enterId.equals(entInfo.getId())){
                    enterprise = enterId;
                    break;
                }
            }
        }
        if(StringUtils.isEmpty(enterprise))
            enterprise = ents[0].getId();
        return enterprise;
    }

    /**
    * @Description: 根据负责人手机号码判断该负责人是否在该租户下，并且返回ID
    * @param: [mobile, tenantId]
    * @return: java.lang.String
    * @author: zhangwce
    * @Date: 2018/5/12
    */
    private String userExistInTenant(String mobile, String tenantId) throws BusinessException {
        log.error("手机号码："+ mobile+",租户ID："+tenantId);
        String info = UserCenter.userExistInTenant(tenantId,mobile,null,null);
        if(StringUtils.isEmpty(info)){
            throw new BusinessException("友户通服务异常");
        }
        log.error("userExistInTenant返回值："+ info);

        Map<String,Object> resultMap = new HashMap<String,Object>();
        try {
            resultMap = objectMapper.readValue(info,Map.class);
        } catch (IOException e) {
            log.error(e.getMessage());
        }

        String userId = "";

        if("1".equals(String.valueOf(resultMap.get("status")) )&&
                ("1002".equals(resultMap.get("code"))
                ||"1003".equals(resultMap.get("code")))
                ){
            UserInfo userInfo = userInfoQuery.getUserIdByContact(mobile,null);
            userId = userInfo.getUserId();
        }

        return userId;
    }

    @RequestMapping(value = "/updateFromOutter")
    @ResponseBody
    public ProjectVO updateFromOutter(@RequestBody ProjectVO project,HttpServletRequest request) throws BusinessException {
        String tenantId = request.getHeader("accountId");
        String enterId = request.getHeader("enterId");
        RuntimeEnvironment.setTenantId(tenantId);
        project.setPkTenant(tenantId);
        if(StringUtils.isEmpty(tenantId))
            throw new BusinessException("未找到对应租户信息");

        String enterprise = "";
        // 根据负责人手机号码判断该负责人是否在该租户下，并且返回ID
        if(StringUtils.isNotEmpty(project.getManagerMobile())){
            String userId = userExistInTenant(project.getManagerMobile(), tenantId);

            if(StringUtils.isNotEmpty(userId)){
                project.setManager(userId);
                enterprise = getOwnEnter(userId,enterId);
            }
        }

        if(StringUtils.isNotEmpty(project.getCreatorMobile())){
            String creatorId = userExistInTenant(project.getCreatorMobile(), tenantId);
            if(StringUtils.isNotEmpty(creatorId)){
                RuntimeEnvironment.setLoginUserId(creatorId);
            }
//            RuntimeEnvironment.setLoginUserId(creatorId);
        }

        return  projectOutterMaintain.updateFromOutter(project,enterprise);
    }

    @RequestMapping(value = "/deleteFromOutter")
    @ResponseBody
    public ProjectVO deleteFromOutter(@RequestBody ProjectVO project,HttpServletRequest request) throws BusinessException {
        String tenantId = request.getHeader("accountId");
        if(StringUtils.isEmpty(tenantId))
            throw new BusinessException("未找到对应租户信息");
        project.setPkTenant(tenantId);
        return projectOutterMaintain.deleteFromOutter(project);
    }

}
